
package com.dhcc.bpm.modules.content.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.constant.FilePathConstant;
import com.dhcc.bpm.common.utils.FileUtils;
import com.dhcc.bpm.common.utils.StringUtils;
import com.dhcc.bpm.modules.content.entity.DocManagement;
import com.dhcc.bpm.modules.content.mapper.DocManagementMapper;
import com.dhcc.bpm.modules.content.service.IDocManagementService;
import com.dhcc.bpm.modules.content.vo.DecompressQueryVo;
import com.dhcc.bpm.modules.content.vo.DocManagementVO;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @ClassName DocManagementServiceImpl
 * @Description  文档管理 服务实现类
 * @Author lijiacheng
 * @Date 2020/2/21 14:16
 * @Version V1.0
 * @Copyright: 2020 东华软件股份有限公司. All rights reserved.
 */

@Service
public class DocManagementServiceImpl extends BaseServiceImpl<DocManagementMapper, DocManagement> implements IDocManagementService {
	private static Logger log = LoggerFactory.getLogger(DocManagementServiceImpl.class);

	private int count;
	@Autowired
	private FastFileStorageClient storageClient;

	private String docPath;
	@Value("${bpm.file-public-path}")
	public void setFileUploadPath(String publicPath) {
		docPath = publicPath + FilePathConstant.DOCPATH;
	}

	@Override
	public IPage<DocManagementVO> selectDocManagementPage(IPage<DocManagementVO> page, DocManagementVO docManagement) {
		return page.setRecords(baseMapper.selectDocManagementPage(page, docManagement));
	}

	@Override
	public DecompressQueryVo selectFilePathById(Long opcPluploadId) {
		return baseMapper.selectFilePathById(opcPluploadId);
	}

	@Override
	public DocManagement seleDocByCode(String opcDirectoryCode) {
		return baseMapper.seleDocByCode(opcDirectoryCode);
	}

	@Override
	public DocManagementVO getDetailSelfById(Long id) {
		return baseMapper.getDetailSelfById(id);
	}

	@Override
	public void downloadAndSaveWord(String filePath,String name,String fileName) {
		byte[] filebyte = null;
		try {
			DownloadByteArray callback = new DownloadByteArray();
			String groupName = filePath.substring(0, filePath.indexOf("/"));
			String path1 = filePath.substring(filePath.indexOf("/") + 1, filePath.length());
			filebyte = storageClient.downloadFile(groupName, path1, callback);
			if(filebyte==null) {
				throw new RuntimeException("文件下载失败");
			}
			FileUtils.byte2File(filebyte, docPath + fileName + "/", name);
		}catch (Exception e) {
			log.info("文件下载失败！",e);
		}
	}

	/**
	 * 解压缩
	 */
	@Override
	public void decompress(String path, String fileName)  {
			try(ZipFile zip = new ZipFile(path+fileName, Charset.forName("GBK"))) {
				//解决中文文件夹乱码

//			System.out.println("name:"+name);
//			String descDir = parent.getParent()+"/";
				String descDir = path;
				System.out.println("descDir:" + descDir);
				deleteDirectory(descDir);
				for (Enumeration<? extends ZipEntry> entries = zip.entries(); entries.hasMoreElements(); ) {
					ZipEntry entry = (ZipEntry) entries.nextElement();
					String zipEntryName = entry.getName();

//				System.out.println("zipEntryName:"+zipEntryName);
					try(InputStream in = zip.getInputStream(entry)) {
						String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
//				System.out.println("OutPath:"+outPath);
						// 判断路径是否存在,不存在则创建文件路径
						File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
						if (!file.exists()) {
							file.mkdirs();
						}
						// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
						if (new File(outPath).isDirectory()) {
							continue;
						}
						// 输出文件路径信息
						System.out.println("OutPath:" + outPath);

						try (FileOutputStream out = new FileOutputStream(outPath)) {
							byte[] buf1 = new byte[1024];
							int len;
							while ((len = in.read(buf1)) > 0) {
								out.write(buf1, 0, len);
							}
						} catch (IOException e) {
							log.error("异常信息：{}", e);
						}
					}catch (IOException e){
						log.error("异常信息：{}", e);
					}
				}
			}catch (IOException e){
				log.error("异常信息：{}", e);
			}

	}

	@Override
	public boolean checkDocFile(String path) {
		count = 0;
		//检查完毕，删除临时文件
		//deleteDirectory(path);
		return checkDoc(path) && count > 0;
	}

	@Override
	public boolean deleteDirectory(String dir){
		//如果dir不以文件分隔符结尾，自动添加文件分隔符
		if(!dir.endsWith(File.separator)){
			dir = dir+File.separator;
		}
		File dirFile = new File(dir);
		//如果dir对应的文件不存在，或者不是一个目录，则退出
		if(!dirFile.exists() || !dirFile.isDirectory()){
			System.out.println("删除目录失败"+dir+"目录不存在！");
			return false;
		}
		boolean flag = true;
		//删除文件夹下的所有文件(包括子目录)
		File[] files = dirFile.listFiles();
		for(int i=0;i<files.length;i++){
			//删除子文件
			if(files[i].isFile()){
				flag = deleteFile(files[i].getAbsolutePath());
				if(!flag){
					break;
				}
			}
			//删除子目录
			else{
				flag = deleteDirectory(files[i].getAbsolutePath());
				if(!flag){
					break;
				}
			}
		}

		if(!flag){
			System.out.println("删除目录失败");
			return false;
		}

		//删除当前目录
		if(dirFile.delete()){
			System.out.println("删除目录"+dir+"成功！");
			return true;
		}else{
			System.out.println("删除目录"+dir+"失败！");
			return false;
		}
	}


	public static boolean deleteFile(String fileName){
		File file = new File(fileName);
		if(file.isFile() && file.exists()){
			Boolean succeedDelete = file.delete();
			if(succeedDelete){
				System.out.println("删除单个文件"+fileName+"成功！");
				return true;
			}
			else{
				System.out.println("删除单个文件"+fileName+"失败！");
				return true;
			}
		}else{
			System.out.println("删除单个文件"+fileName+"失败！");
			return false;
		}
	}

	public Boolean checkDoc(String path) {
		File file = new File(path);
		File[] files = file.listFiles();

		if(files!=null) {
			for (File tempFile : files) {
				String fileName = tempFile.getName();
				String[] arry = fileName.split("_");
				if (tempFile.isDirectory() && arry.length == 5) {
					String url = tempFile.getAbsolutePath();
					String realUrl="";
					String type = arry[0].toLowerCase();
					String docType = selectDocType(type);
					//String docType = arry[0].toLowerCase();
					String docCode = arry[1];
					String parentId = arry[2];
					String docName = arry[3];
					String perms = arry[4];
					if(!StringUtils.isNotEmpty(docType) || !StringUtils.isNotEmpty(docCode) || !StringUtils.isNotEmpty(docName) || !StringUtils.isNotEmpty(perms)) {
						return false;
					}
					if(!"1".equals(docType) && !"2".equals(docType) && !"3".equals(docType) && !"4".equals(docType)) {
						return false;
					}
					if(("0".equals(parentId) || "".equals(parentId)) && !StringUtils.checkStrIsNum(docCode)) {
						return false;
					}
					//计数压缩包中是否存在符合格式的文件夹
					count++;
					if(!checkDoc(url)) {
						return false;
					}
				}
			}
		}else if(count == 0){
			return false;
		}

		return true;
	}

	//查询文档类型
	private String selectDocType(String type) {
		String  docType = "";
		if ("f".equals(type)) {
			docType =  "1";
		} else if ("m".equals(type)) {
			docType =  "2";
		} else if ("c".equals(type)) {
			docType =  "3";
		} else if ("w".equals(type)) {
			docType =  "4";
		}
		return docType;
	}

}
